/**
 * 实现文件分析
 * 创建者：Carburn Ashroom
 * 2025.2.11
 */

#include "file.h"

namespace File {

    QList<Data::Road> Option::exhaust() const
    {
        Data::Road res {value,loves};
        if (not child_ques)
            return QList<Data::Road>{res};
        QList<Data::Road> ex;
        for (auto& cr : child_ques->exhaust())
            ex.append(res+cr);
        return ex;
    }

    void Option::set_option(QStringList&& message)
    {
        value = message.takeFirst();
        loves = std::move(message);
    }

    QList<Data::Road> Question::exhaust() const
    {
        QList<Data::Road> roads;
        for (const auto& op : options)
            roads.append(op.exhaust());
        return roads;
    }

    void Question::read_ques(QTextStream& file)
    {
        QStringList first_ques {file.readLine().split(' ')};
        first_ques.removeFirst();
        Option prev {std::move(first_ques)};
        shared_ptr<Question> child;
        for ( ; ; ) {
            QString line {file.readLine()};
            if (line.isEmpty())
                break;
            auto ques = line.split(' ');
            auto control = ques.takeFirst();
            if (control == '+') {
                if (child) {
                    prev.set_child(child);
                    child.reset();
                }
                options.append(std::move(prev));
                prev = Option{std::move(ques)};
            }
            else {
                if (not child)
                    child.reset(new Question);
                child->options.emplaceBack(std::move(ques));
            }
        }
        if (child)
            prev.set_child(child);
        options.append(std::move(prev));
    }

    const QList<Data::Roads>& Mayu::operator[](const QString& name) const
    {
        for (const auto& lead : roles)
            if (lead == name)
                return lead.road_list();
        return roles.first().road_list();       // 仅防警告，不可能到达此处
    }

    void Mayu::read_file(const QString& file)
    {
        QFile f {file};
        f.open(QIODevice::ReadOnly);
        QTextStream f_str {&f};
        needs = Data::Favorability{f_str};
        for (auto& name : needs.roles())
            roles.emplaceBack(name);
        QList<Question> questions;
        while (not f_str.atEnd())
            questions.emplaceBack(f_str);
        auto first_ques = questions.takeFirst();
        for (auto r : first_ques.exhaust())
            analyse(std::move(r), questions);
    }

    void Mayu::analyse(Data::Road&& road, const QList<Question>& later)
    {
        if (later.isEmpty()) {
            QStringList lovers {needs.select(road.favors())};
            if (lovers.isEmpty()) {
                bachelor.append(std::move(road));
                return;
            }
            for (auto& r : roles)
                if (r.my_road(lovers)) {
                    lovers.removeFirst();
                    r.add_road(lovers, road);
                    break;
                }
        }
        else {
            auto ques = later;
            auto fq = ques.takeFirst();
            for (auto& r : fq.exhaust())
                analyse(road+r, ques);
        }
    }

}
